import { Button, Card, Descriptions, Divider, Empty, Icon, Spin } from 'antd'
import React, { useState } from 'react'
import classNames from 'classnames'
import { useRequest } from 'ahooks'
import { Link } from 'umi'
import HttpCallEditor from '../HttpCall/HttpCallEditor'
import InvocationConfig from '../Invocation/InvocationConfig'
import styles from './index.less'
import { DataSourceType, TaskType } from './settings'
import TaskContent from './components/TaskContent'
import DataSourceContent from './components/DataSourceContent'
import EndNodeContent from './components/EndNodeContent'
import ProcessStatus from './ProcessStatus'
import { DATASOURCE_ID_HEADER } from './LogPage'
import FooterToolbar from '@/components/FooterToolbar'
import ScrollBar from '@/components/ScrollBar'
import request from '@/utils/request'
import ReadOnlyModal from '@/components/ReadOnlyModal'
import IconFont from '@/components/IconFont'
import { toPath } from '@/utils/router'

const { Item } = Descriptions

const StatusMap = {
  0: '执行成功',
  1: '业务异常',
  2: '程序异常',
  3: '网络异常',
}

const TaskTypeMap = {
  [TaskType.VALIDATION]: '报文校验',
  [TaskType.TRANSFORM]: '报文转换',
  [TaskType.HTTP_CALL]: 'HTTP调用',
  [TaskType.INVOCATION]: '本地调用',
  [TaskType.CUSTOM]: '自定义',
}

const DataSourceMap = {
  [DataSourceType.HTTP]: 'HTTP数据源',
  [DataSourceType.NONE]: '无数据源',
}

function renderTitle(taskName, isCurrent) {
  if (isCurrent)
    return <span style={{ color: 'rgba(82, 196, 26, 0.85)' }}>{taskName}</span>

  return <span style={{ color: 'rgba(0, 0, 0, 0.45)' }}>{taskName}</span>
}

export const descriptionProps = {
  className: 'description-list',
  column: 4,
  bordered: true,
}

function LogDetail({ record, datasourceId, goToStep }) {
  const hasError = record.status === 2

  const {
    loading: taskLogsLoading,
    data = {
      taskLogs: [],
      processLogContent: {},
    },
  } = useRequest(() =>
    request.get(
      `/processLog/listTaskLogs?processLogId=${
        record.processLogId
      }&shardingKey=${record.shardingKey || ''}`,
      {
        headers: {
          [DATASOURCE_ID_HEADER]: datasourceId,
        },
      },
    ),
  )

  const {
    taskLogs,
    processLogContent: {
      dataSourceName,
      dataSourceType,
      dataSourceCode,
      requestContent,
      responseContent,
      contentId,
    } = {},
  } = data

  const requestContentObj = requestContent ? JSON.parse(requestContent) : {}
  requestContentObj.contentId = `${contentId}_request`
  const responseContentObj = responseContent ? JSON.parse(responseContent) : {}
  responseContentObj.contentId = `${contentId}_response`

  const [current, setCurrent] = useState({})

  function renderTaskName(task) {
    const { taskName, taskType, taskId, taskVersionId } = task

    if (taskType === TaskType.HTTP_CALL) {
      return (
        <ReadOnlyModal trigger={<a>{taskName}</a>} width={850} title="HTTP调用">
          <HttpCallEditor versionId={taskVersionId} readOnly />
        </ReadOnlyModal>
      )
    }

    if (taskType === TaskType.INVOCATION) {
      return (
        <ReadOnlyModal trigger={<a>{taskName}</a>} width={700} title="本地调用">
          <InvocationConfig versionId={taskVersionId} readOnly />
        </ReadOnlyModal>
      )
    }

    if (taskType === TaskType.TRANSFORM) {
      return (
        <Link to={toPath(`/transformer/${taskId}?versionId=${taskVersionId}&readOnly=true`)}>
          {taskName}
        </Link>
      )
    }

    if (taskType === TaskType.VALIDATION) {
      return (
        <Link to={toPath(`/validator/${taskId}?versionId=${taskVersionId}&readOnly=true`)}>{taskName}</Link>
      )
    }

    return taskName
  }

  return (
    <>
      <Card title="日志详情" bodyStyle={{ padding: '16px 16px 128px 32px' }}>
        <div className="ant-detail-title">基本信息</div>
        <Descriptions {...descriptionProps}>
          <Item label="流程名称">{record.processName}</Item>
          <Item label="流程编码">{record.processCode}</Item>
          <Item label="流程生效版本号">{record.processVersionNumber}</Item>
          <Item label="事务ID">{record.transactionId}</Item>
          <Item label="实例ID">{record.instanceId}</Item>
          <Item label="轨迹ID">{record.traceId}</Item>
          <Item label="分片键">{record.shardingKey}</Item>
          <Item label="扩展信息">{record.extension}</Item>
          <Item label="客户端IP">{record.clientIp}</Item>
          <Item label="服务端IP">{record.serverIp}</Item>
          <Item label="开始时间">{record.startTime}</Item>
          <Item label="结束时间">{record.endTime}</Item>
          <Item label="流程耗时">{`${record.duration} ms`}</Item>
          <Item label="异常编码">{record.errorCode}</Item>
          <Item label="异常描述信息">{record.errorDesc}</Item>
          <Item label="执行状态">{StatusMap[record.status]}</Item>
        </Descriptions>
        <Divider />
        <div className="ant-detail-title">任务执行记录</div>
        <div className={classNames(styles.steps)} style={{ textAlign: 'left', marginBottom: 30 }}>
          {[0, 1, 2, 3].map(status => (
            <div key={status} className={styles.stepsItem} style={{ minWidth: 0, marginRight: 16 }}>
              <ProcessStatus status={status} />
            </div>
          ))}
        </div>
        <ScrollBar autoHide autoHeight autoHeightMin="56px">
          <Spin spinning={taskLogsLoading}>
            {taskLogs.length === 0
              ? (
              <Empty />
                )
              : (
              <div className={classNames(styles.steps)}>
                {requestContent && (
                  <div className={styles.stepsItem} key={requestContentObj.contentId}>
                    <div
                      className={classNames(styles.stepsItemIcon, [styles.finish])}
                      onClick={() => setCurrent(requestContentObj)}
                    >
                      <IconFont type="icon-playfill" />
                    </div>
                    <div
                      className={styles.stepsItemContent}
                      onClick={() => setCurrent(requestContentObj)}
                    >
                      {renderTitle(
                        dataSourceName,
                        current.contentId === requestContentObj.contentId,
                      )}
                    </div>
                    <div className={classNames(styles.stepsItemLine, [styles.lineFish])} />
                  </div>
                )}
                {taskLogs.map((taskLog, index) => {
                  const isLastLog = index === taskLogs.length - 1
                  const isError = isLastLog && hasError
                  const isBizError = taskLog.status === 1
                  const isNetworkError = taskLog.status === 3

                  const isCurrent = current.taskLogId === taskLog.taskLogId

                  return (
                    <div className={styles.stepsItem} key={taskLog.taskLogId}>
                      <div
                        className={classNames(styles.stepsItemIcon, [
                          isError
                            ? styles.error
                            : isBizError
                              ? styles.warn
                              : isNetworkError
                                ? styles.network
                                : styles.finish,
                        ])}
                        onClick={() => setCurrent(taskLog)}
                      >
                        {isError
                          ? (
                          <Icon type="close" />
                            )
                          : isBizError
                            ? (
                          <Icon type="exclamation" />
                              )
                            : isNetworkError
                              ? (
                          <IconFont type="icon-Network-Error" />
                                )
                              : (
                          <Icon type="check" />
                                )}
                      </div>
                      <div className={styles.stepsItemContent} onClick={() => setCurrent(taskLog)}>
                        {renderTitle(taskLog.taskName, isCurrent)}
                      </div>
                      <div className={classNames(styles.stepsItemLine, [styles.lineFish])} />
                    </div>
                  )
                })}

                {responseContent && (
                  <div className={styles.stepsItem} key={responseContentObj.contentId}>
                    <div
                      className={classNames(styles.stepsItemIcon, [styles.finish])}
                      onClick={() => setCurrent(responseContentObj)}
                    >
                      <IconFont type="icon-stop" />
                    </div>
                    <div
                      className={styles.stepsItemContent}
                      onClick={() => setCurrent(responseContentObj)}
                    >
                      {renderTitle('结束', current.contentId === responseContentObj.contentId)}
                    </div>
                    <div className={classNames(styles.stepsItemLine, [styles.lineFish])} />
                  </div>
                )}
              </div>
                )}
          </Spin>
        </ScrollBar>

        {current.contentId && current.contentId.endsWith('request') && (
          <>
            {dataSourceType !== DataSourceType.NONE && (
              <>
                <Divider />
                <div className="ant-detail-title">数据源信息</div>
                <Descriptions {...descriptionProps}>
                  <Item label="数据源类型">{DataSourceMap[dataSourceType]}</Item>
                  <Item label="数据源名称">{dataSourceName}</Item>
                  <Item label="数据源编码">{dataSourceCode}</Item>
                </Descriptions>
              </>
            )}

            <Divider />
            <div className="ant-detail-title">
              {dataSourceType === DataSourceType.NONE ? '开始节点信息' : '数据源详细信息'}
            </div>
            <DataSourceContent dataSourceType={dataSourceType} content={current} />
          </>
        )}

        {current.contentId && current.contentId.endsWith('response') && (
          <>
            <Divider />
            <div className="ant-detail-title">结束节点信息</div>
            <EndNodeContent dataSourceType={dataSourceType} content={current} />
          </>
        )}

        {current.taskLogId
          ? (
          <>
            <Divider />
            <div className="ant-detail-title">任务基本信息</div>
            <Descriptions {...descriptionProps}>
              <Item label="任务类型">{TaskTypeMap[current.taskType]}</Item>
              <Item label="任务名称">{renderTaskName(current)}</Item>
              <Item label="任务编码">{current.taskCode}</Item>
              {current.taskType !== TaskType.CUSTOM && (
                <Item span={6} label="任务生效版本号">
                  {current.taskVersionNumber}
                </Item>
              )}
              <Item label="任务开始时间">{current.startTime}</Item>
              <Item label="任务结束时间">{current.endTime}</Item>
              <Item label="任务耗时">{`${current.duration} ms`}</Item>
            </Descriptions>
            <Divider />
            <div className="ant-detail-title">任务详细信息</div>
            <TaskContent taskLog={current} datasourceId={datasourceId} />
          </>
            )
          : null}
      </Card>
      <FooterToolbar className="right">
        <Button type="primary" ghost onClick={() => goToStep(1)}>
          返回
        </Button>
      </FooterToolbar>
    </>
  )
}

export default LogDetail
